 package ChatNI;


import Controller.ChatController;
import java.net.UnknownHostException;
import java.util.ArrayList;
import ourMessage.*;
import Model.*;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * Cette classe représente toutes les connexions entrantes et sortantes de l'application,
 * 
 * 
 *
 * @author Idriss
 */
public class ChatNI implements Runnable {
   
        private static ChatController ctrl;
        private Receiver MessageReceiver;
        private Sender MessageSender;
        private ArrayList<FileReceiver> FileReceiverList;
        private static ArrayList<FileSender> FileSenderList;
        private FileReceiver filerecp;
        private ChatModel model;
       // private String lm;
        
    /**
     * Constructeur de la classe,il instancie le sender,le receiver, le FileReceveiver
     *
     */
    public ChatNI() {
                
               
                MessageSender = new Sender();
                FileReceiverList = new ArrayList<FileReceiver>();
                FileSenderList = new ArrayList<FileSender>(); 
                MessageReceiver =new Receiver();

               model= new ChatModel(null);
        }
        
    /**
     * Cette méthode permet d'instancier le controller
     *
     * @param ctrl
     */
    public void setController(ChatController ctrl) {
            this.ctrl = ctrl;
        }
        
        //Notification des messages reçus

    /**
     *Notification des messages reçus,cette méthode joue le rôle d'aiguilleuse de tout les message reçu.
     * Elle permet d'optimiser le traitement des message en fonction de l'instance de la classe.
     * Par exemple:  if(message.getClass() == Hello.class){
     *                   ChatController.helloProcessing((Hello) message);
                        
     *                  }
     * Dans ce traitement on teste si le message reçu est une instance de la classe Hello, et on appelle la méthode HelloProcessing qui
     * qui va permettre d'envoyer un Acknowlegment ou si on l'ajoute seulement dans notre liste de user.
     * 
     * 
     * @param message
     * @throws UnknownHostException
     * @throws NullPointerException
     */
            public  void Notifmsgrecu(Message message) throws UnknownHostException, NullPointerException {
               
                        if(message.getClass() == Hello.class){
                                
                                ChatController.helloProcessing((Hello) message);
                                
                        }else if(message.getClass() == Bye.class){
                                
                                ChatController.byeProcessing((Bye) message);
                                
                        }else if(message.getClass() == Text.class){
                                
                                ChatController.messageProcessing((Text) message);
                                
                        }else if(message.getClass() == FileTransfertDemand.class){
                               
                                ChatController.sendfiledemandProcessing((FileTransfertDemand) message);
                                
                                
                        }else if(message.getClass() == FileTransfertConfirmation.class){
                                
                                ChatController.performTransfertFile();
                                
                        }else if(message.getClass() == FilePart.class){
                                
                                ChatController.fileProcessing((FilePart)message);
                        }
                        else if(message.getClass() == FileTransfertCancel.class){
                                
                                ChatController.perfomcanceling(((FileTransfertCancel)message).getlogin());
                        }
                }
  
    /**
     *Cette méthode permet d'envoyer un bye.
     * 
     * @throws UnknownHostException
     */
    public void SendBye() throws UnknownHostException{
                
                Bye b = new Bye(ctrl.getLocalUsername());
                System.out.println("On broadcast un bye"+b);
                
                MessageSender.BroadCastMessage(b);
        }
        
    /**
     * Cette méthode est appelé à la connection d'un utilisateur local pour notifier au autre qu'il est connecté.
     * elle est aussi utilisé pour l'envoi du HelloAck en mettant le boolean IsAck à true.
     * 
     * 
     * @param isAck
     * @param RemoteUsername
     * @throws UnknownHostException
     */
    public void SendHello(boolean isAck, String RemoteUsername) throws UnknownHostException{
                 
                Hello h = new Hello(ctrl.getLocalUsername(),isAck);
                
                if(isAck){
                        System.out.println("On doit envoyer un ack");
                        for(int i=0;i<model.getUserList().size();i++){
                            if(model.getUserList().contains(RemoteUsername)){
                                
                                System.out.println("addresse: "+model.adrss(RemoteUsername));
                                MessageSender.SendMessage(h,model.adrss(RemoteUsername));
                            }
                        }           
                }else{ 
                        System.out.println("On broadcast un hello");
                        MessageSender.BroadCastMessage(h);
                }
                
        }
        
    /**
     *Cette méthode permet d'envoyer un message à un user unique ou à plusieurs users dans repertorier dans une liste.
     * 
     * @param m
     *          m: Message a envoyé.
     * @param UsernameList
     *              la liste des utilisateurs à qui il faut envoyer le message.
     */
    public void SendMessage(Message m, List UsernameList){
            
                if(UsernameList.size() == 1){
                       
                                System.out.println("addresse IP: "+model.adrss(((String)UsernameList.get(0))));
                                MessageSender.SendMessage(m,model.adrss((String)UsernameList.get(0)));
                            
                        }         
                else{
                        
                    for (Object UsernameList1 : UsernameList) {
                        MessageSender.SendMessage(m, model.adrss((String) UsernameList1));
                        System.out.println("jssjs");
                    }
                }
        }
        

    /**
     *Cette méthode est appelé pour faire une demande de transfert de fichier
     * @param localUsername
     * @param fileName
     * @param size
     * @param portClient
     * @param idDemand
     * @param UsernameList
     */
            public void SendFileDemand(String localUsername, String fileName, long size, int portClient, int idDemand,List UsernameList){
            FileTransfertDemand ftd= new FileTransfertDemand(localUsername, fileName, size, portClient,idDemand);
            SendMessage(ftd, UsernameList);
        }
        
         

    /**
     *Cette fonction permet d'envoyer une confirmation au demandeur.
     * 
     * @param username
     * @param isAccepted
     * @param idDemand
     * @param UsernameList
     * @throws IOException
     */
            public void TransfertConfirmation(String username, boolean isAccepted, int idDemand,List UsernameList) throws IOException{
            FileTransfertConfirmation ftc = new FileTransfertConfirmation(username, isAccepted, idDemand);
            SendMessage(ftc, UsernameList);
           
                
                        
                        String filename = ChatController.getFilename();
                       
                        FileReceiverList.add(new FileReceiver(model.adrss((String)UsernameList.get(0)), 2015,filename));
                        
                        System.out.println("le nom du fichier"+filename);
                    }
       
     
        
       

    /**
     *Pour refuser la demande de transfert de fichier
     * @param username
     * @param idDemand
     * @param UsernameList
     */
            public void TransfertCancel(String username, int idDemand,List UsernameList){
            FileTransfertCancel ftca = new FileTransfertCancel(username,idDemand);
            SendMessage(ftca, UsernameList);
        }
        
       

    /**
     * Pour transferer le fichier
     * @param username
     * @param file
     * @param portEnvoi
     * @throws IOException
     */
            public static void SendFile(String username, File file,int portEnvoi) throws IOException{
            System.out.println("partie0 "+portEnvoi+" "+file.toString());
            FileSender FS = new FileSender(portEnvoi,file,file.length());
            FileSenderList.add(FS);
            System.out.println("envoi OK");
        }
        
        /**
         * @return the messageSender
         */
        public Sender getMessageSender() {
                return MessageSender;
        }

        /**
         * @param messageSender the messageSender to set
         */
        public void setMessageSender(Sender messageSender) {
                MessageSender = messageSender;
        }
    /**
         * @return the messageReceiver
         */
        public Receiver getMessageReceiver() {
                return MessageReceiver;
        }
         /**
         * @param messageReceiver the messageReceiver to set
         */
        public void setMessageReceiver(Receiver messageReceiver) {
                MessageReceiver = messageReceiver;
        }
        
        public void run(){
            
        }

    

    
        
}
